return self;
}
-static GskVulkanImage *
-gsk_vulkan_image_new_staging (GdkVulkanContext *context,
- guchar *data,
- gsize width,
- gsize height,
- gsize stride)
+static void
+gsk_vulkan_image_upload_data (GskVulkanImage *self,
+ guchar *data,
+ gsize width,
+ gsize height,
+ gsize data_stride)
{
VkMemoryRequirements requirements;
- GskVulkanImage *self;
- guchar *mem;
gsize mem_stride;
-
- self = gsk_vulkan_image_new (context,
- width,
- height,
- VK_IMAGE_TILING_LINEAR,
- VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
- VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
+ guchar *mem;
mem_stride = width * 4;
- vkGetImageMemoryRequirements (gdk_vulkan_context_get_device (context),
+ vkGetImageMemoryRequirements (gdk_vulkan_context_get_device (self->vulkan),
self->vk_image,
&requirements);
if (mem_stride % requirements.alignment != 0)
mem = gsk_vulkan_memory_map (self->memory);
- if (stride == width * 4 && stride == mem_stride)
+ if (data_stride == width * 4 && data_stride == mem_stride)
{
- memcpy (mem, data, width * height * 4);
+ memcpy (mem, data, data_stride * height);
}
else
{
for (gsize i = 0; i < height; i++)
{
- memcpy (mem + i * mem_stride, data + i * stride, width * 4);
+ memcpy (mem + i * mem_stride, data + i * data_stride, width * 4);
}
}
gsk_vulkan_memory_unmap (self->memory);
-
- return self;
}
static void
}
GskVulkanImage *
-gsk_vulkan_image_new_from_data (GdkVulkanContext *context,
- VkCommandBuffer command_buffer,
- guchar *data,
- gsize width,
- gsize height,
- gsize stride)
+gsk_vulkan_image_new_from_data_via_staging_image (GdkVulkanContext *context,
+ VkCommandBuffer command_buffer,
+ guchar *data,
+ gsize width,
+ gsize height,
+ gsize stride)
{
GskVulkanImage *self, *staging;
- staging = gsk_vulkan_image_new_staging (context, data, width, height, stride);
+ staging = gsk_vulkan_image_new (context,
+ width,
+ height,
+ VK_IMAGE_TILING_LINEAR,
+ VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
+ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
+
+ gsk_vulkan_image_upload_data (staging, data, width, height, stride);
self = gsk_vulkan_image_new (context,
width,
}
});
+ /* XXX: Is this okay or do we need to keep the staging image around until the commands execute */
gsk_vulkan_image_free (staging);
gsk_vulkan_image_ensure_view (self);
return self;
}
+GskVulkanImage *
+gsk_vulkan_image_new_from_data_directly (GdkVulkanContext *context,
+ VkCommandBuffer command_buffer,
+ guchar *data,
+ gsize width,
+ gsize height,
+ gsize stride)
+{
+ GskVulkanImage *self;
+
+ self = gsk_vulkan_image_new (context,
+ width,
+ height,
+ VK_IMAGE_TILING_LINEAR,
+ VK_IMAGE_USAGE_SAMPLED_BIT,
+ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
+
+ gsk_vulkan_image_upload_data (self, data, width, height, stride);
+
+ vkCmdPipelineBarrier (command_buffer,
+ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ 0,
+ 0, NULL,
+ 0, NULL,
+ 1, (VkImageMemoryBarrier[1]) {
+ {
+ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
+ .srcAccessMask = VK_ACCESS_HOST_WRITE_BIT,
+ .dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
+ .oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED,
+ .newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
+ .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .image = self->vk_image,
+ .subresourceRange = {
+ .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+ .baseMipLevel = 0,
+ .levelCount = 1,
+ .baseArrayLayer = 0,
+ .layerCount = 1
+ }
+ }
+ });
+
+ gsk_vulkan_image_ensure_view (self);
+
+ return self;
+}
+
+GskVulkanImage *
+gsk_vulkan_image_new_from_data (GdkVulkanContext *context,
+ VkCommandBuffer command_buffer,
+ guchar *data,
+ gsize width,
+ gsize height,
+ gsize stride)
+{
+ switch (GSK_VULKAN_UPLOAD_IMAGE_DEFAULT)
+ {
+ default:
+ g_assert_not_reached ();
+ /* fall through */
+ case GSK_VULKAN_UPLOAD_DIRECTLY:
+ return gsk_vulkan_image_new_from_data_directly (context, command_buffer, data, width, height, stride);
+ case GSK_VULKAN_UPLOAD_VIA_STAGING_IMAGE:
+ return gsk_vulkan_image_new_from_data_via_staging_image (context, command_buffer, data, width, height, stride);
+ }
+}
+
void
gsk_vulkan_image_free (GskVulkanImage *self)
{